/*
 * TMC6200.c
 *
 *  Created on: 14.03.2018
 *      Author: ED
 */

#include "TMC6200.h"
#include "spi.h"
#include "TMC6200_Fields.h"
// => SPI wrapper
uint8_t tmc6200_readwriteByte(TMC6200_Handle handle, uint8_t data, uint8_t lastTransfer){
	uint8_t recbuff;
	// Actuate chipselect
	gpio_bit_write(handle->nCSgpioHandle, handle->nCSgpioNumber, RESET);
  	delay_us(1);
	while(RESET == (uint8_t)spi_i2s_flag_get(handle->spiHandle, SPI_FLAG_TBE));
	spi_i2s_data_transmit(handle->spiHandle,data);
	while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE));
    recbuff = (uint8_t)spi_i2s_data_receive(handle->spiHandle);

	if(lastTransfer==true){
		gpio_bit_write(handle->nCSgpioHandle, handle->nCSgpioNumber, SET);
		delay_us(1);
	}
	return recbuff;
}
// <= SPI wrapper

// spi access
int tmc6200_readInt(TMC6200_Handle handle, uint8_t address)
{
	// clear write bit
	address = TMC_ADDRESS(address);

	// write address
	tmc6200_readwriteByte(handle, address, false);

	// read data
	int value = tmc6200_readwriteByte(handle, 0, false);
	value <<= 8;
	value |= tmc6200_readwriteByte(handle, 0, false);
	value <<= 8;
	value |= tmc6200_readwriteByte(handle, 0, false);
	value <<= 8;
	value |= tmc6200_readwriteByte(handle, 0, true);

	return value;
}

void tmc6200_writeInt(TMC6200_Handle handle, uint8_t address, int value)
{
	// write address
	tmc6200_readwriteByte(handle, address | TMC6200_WRITE_BIT, false);

	// write value
	tmc6200_readwriteByte(handle, 0xFF & (value>>24), false);
	tmc6200_readwriteByte(handle, 0xFF & (value>>16), false);
	tmc6200_readwriteByte(handle, 0xFF & (value>>8), false);
	tmc6200_readwriteByte(handle, 0xFF & (value>>0), true);
}


void tmc6200_enable(TMC6200_Handle handle)
{
	//Disable driver
	gpio_bit_write(handle->EngpioHandle, handle->EngpioNumber,RESET);
	//Wait for driver to come online
	osDelay(10);

	//Enable driver
	gpio_bit_write(handle->EngpioHandle, handle->EngpioNumber, SET);
	osDelay(10);

	//while(tmc6200_readInt(handle,TMC6200_GCONF) != 0);

	// Wait for the DRV8301 registers to update
	osDelay(1);

	return;
}


void tmc6200_setGCONF(TMC6200_Handle handle,TMC6200_GCONF_Reg reg)
{
	int32_t value=0x00;
	value |= (reg.driverDisable << TMC6200_DISABLE_SHIFT)&TMC6200_DISABLE_MASK;
	value |= (reg.intfaceMode<<TMC6200_SINGLELINE_SHIFT)&TMC6200_SINGLELINE_MASK;
	value |= (reg.faultDirect<<TMC6200_FAULTDIRECT_SHIFT)&TMC6200_FAULTDIRECT_MASK;
	value |= (reg.amplification<<TMC6200_AMPLIFICATION_SHIFT)&TMC6200_AMPLIFICATION_MASK;
	value |= (reg.amplifierSwitch<<TMC6200_CURRENT_ZERO_SHIFT)&TMC6200_CURRENT_ZERO_MASK;
	value |= (reg.testMode<<TMC6200_TEST_MODE_SHIFT)&TMC6200_TEST_MODE_MASK;
	
	tmc6200_writeInt(handle,TMC6200_GCONF,value);

}
void tmc6200_setDRVReg(TMC6200_Handle handle,TMC6200_DRV_Reg reg)
{
	int32_t value=0x00;
	
	value |= (reg.BBMCLKS << TMC6200_BBMCLKS_SHIFT)&TMC6200_BBMCLKS_MASK;
	value |= (reg.OTSELECT << TMC6200_OTSELECT_SHIFT)&TMC6200_OTSELECT_MASK;
	value |= (reg.DRVSTRENGTN << TMC6200_DRVSTRENGTH_SHIFT)&TMC6200_DRVSTRENGTH_MASK;

	tmc6200_writeInt(handle,TMC6200_DRV_CONF,value);	
}